﻿'               Universidad del Cauca
'       Ingeniería en Automática Industrial
'
'Archivo principal. En este modulo se maneja todo.
'Este hace uso del namespace USBConverter y MSDNImports creados anteriormente.
'
'Creado por:    Mónica Isabel Urbano
'               Rowinson Gallego Medina
'
'Taller de Sistemas Digitales
'   Ing. Vladimir Trujillo

Imports USBConverter.USBConverter
Imports Microsoft.Win32.SafeHandles

Public Class GUI

    '[Atributos]
    Private miGUID As Guid = New Guid("47D6D24F-61D6-4eb4-B91E-2000366126E6")     'Este GUID enlaza mi aplicación con el dispositivo. Es decir, el que especifico en el .INF
    Private Midispositivo As USBDevice = New USBDevice    'Creamos un una instancia de USBDevice (Es decir, creamos un dispositivo)
    Private Mensaje_actuadores As String = "\0\0\0\0\0\0\0\0"
    Private Mensaje_sensores(40) As Byte

    Private Codigo_compilado(255) As Byte
    Dim longitud_codigo As Integer = 0

    '   Actuadores
    Private Carga1Val, Carga2Val, Motor1Val, Motor2Val, CargaCtrl1, CargaCtrl2 As String


    'Constructor

    Public Sub New()

        ' Llamada necesaria para el Diseñador de Windows Forms.
        InitializeComponent()

        ' Agregue cualquier inicialización después de la llamada a InitializeComponent().

        'Todos los controles deshabilitados
        Mensajes.ReadOnly = True
        Deshabilitar.Enabled = False

        BajarCargaCtrl1.Enabled = False
        BajarCargaCtrl2.Enabled = False

        Actuadores.Enabled = False
        Sensores.Enabled = False

        Globo.Visible = True


        'A ceros todos los controles
        ResetValores()

    End Sub

    'Función de envío del Mensaje total al PIC

    Private Sub EnvioMensaje()

        'Envío de información al PIC para que se ejecute, en el formato:
        '   "$Carga1,Carga2,Motor1,Motor2,CargCtrl1,CargaCtrl2#"
        '   Ejemplo:    "$1,0,I,D,95,10#"
        '   Esto es: Carga 1: ON, Carga 2: OFF, Motor 1: Izquierda, Motor 2: Derecha, CargaCtrl 1 al 95% y CargaCtrl 2 al 10%
        Mensaje_actuadores = "$" + Carga1Val + "," + Carga2Val + "," + Motor1Val + "," + Motor2Val + "," + CargaCtrl1 + "," + CargaCtrl2 + "#"
        Midispositivo.Send(System.Text.Encoding.ASCII.GetBytes(Mensaje_actuadores))

    End Sub

    'Reinicio de valores de los actuadores

    Private Sub ResetValores()
        'Reiniciamos todos los controles. Sucede cuando hay una deshabilitación del dispositivo,
        'o cuando se crea la clase GUI del programa, ...

        Carga1Val = "0"
        Carga2Val = "0"


        Motor1Val = "O"
        Motor2Val = "O"

        CargaCtrl1 = "0"
        CargaCtrlVal1.Text = "0"
        CargaCtrl2 = "0"
        CargaCtrlVal2.Text = "0"

        BajarCargaCtrl1.Enabled = False
        BajarCargaCtrl2.Enabled = False

        CargaOff1.Enabled = False
        CargaOff2.Enabled = False
        CargaOn1.Enabled = True
        CargaOn2.Enabled = True

        MotorOff1.Enabled = False
        MotorOff2.Enabled = False

        ProgramarDispositivo.Enabled = False

    End Sub

    'Cierre de la aplicación

    Private Sub GUI_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
        Globo.Visible = False
        Globo.Dispose()
        If Midispositivo.Estado = True Then
            Midispositivo.Finish()
        End If
    End Sub

    'Función de Habilitación o inicialización del dispositivo USB

    Private Sub Habilitar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Habilitar.Click

        Midispositivo.Init(miGUID)

        If Midispositivo.Estado = True Then
            Mensajes.AppendText(vbCr + "[Correcto:] Dispositivo inicializado")

            Actuadores.Enabled = True
            Sensores.Enabled = True
            ProgramarDispositivo.Enabled = True

            Habilitar.Enabled = False
            Deshabilitar.Enabled = True

            Globo.BalloonTipTitle = "USBConverter - Universidad del Cauca"
            Globo.BalloonTipText = "Se ha establecido comunicación con el dispositivo..."
            Globo.ShowBalloonTip(5)

        Else
            Mensajes.AppendText(vbCr + "[Error:] No se encuentra dispositivo!")
        End If
        Mensajes.ScrollToCaret()

        EnvioMensaje()

    End Sub

    'Función de verificacion de conexión con el Dispositivo

    Private Sub Verificar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Verificar.Click
        If Midispositivo.Estado = True Then
            Mensajes.AppendText(vbCr + "[Correcto:] El dispositivo está conectado")
        Else
            Mensajes.AppendText(vbCr + "[Error:] No se encuentra dispositivo!")
        End If
        Mensajes.ScrollToCaret()


    End Sub

    'Función de Deshabilitar el dispositivo

    Private Sub Deshabilitar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Deshabilitar.Click
        Midispositivo.Finish()

        If Midispositivo.Estado = False Then
            Mensajes.AppendText(vbCr + "[Correcto:] Se ha deshabilitado el dispositivo")
            Actuadores.Enabled = False
            Sensores.Enabled = False

            ResetValores()

            Habilitar.Enabled = False

            Globo.BalloonTipTitle = "USBConverter - Universidad del Cauca"
            Globo.BalloonTipText = "Se ha deshabilitado la comunicación con USBConverter"
            Globo.ShowBalloonTip(5)
        Else
            Mensajes.AppendText(vbCr + "[Error:] No se pudo deshabilitar dispositivo!")
        End If

        Mensajes.ScrollToCaret()
        Deshabilitar.Enabled = False
        Habilitar.Enabled = True
    End Sub

    'ACTUADOR 1: Carga encendida 

    Private Sub CargaOn1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CargaOn1.Click

        Carga1Val = "1"
        EnvioMensaje()
        CargaOff1.Enabled = True
        CargaOn1.Enabled = False

    End Sub

    'ACTUADOR 1: Carga apagada

    Private Sub CargaOff1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CargaOff1.Click

        Carga1Val = "0"
        EnvioMensaje()

        CargaOn1.Enabled = True
        CargaOff1.Enabled = False

    End Sub

    'ACTUADOR 2: Carga encendida

    Private Sub CargaOn2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CargaOn2.Click

        Carga2Val = "1"
        EnvioMensaje()

        CargaOff2.Enabled = True
        CargaOn2.Enabled = False

    End Sub

    'ACTUADOR 2: Carga apagada

    Private Sub CargaOff2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CargaOff2.Click

        Carga2Val = "0"
        EnvioMensaje()

        CargaOn2.Enabled = True
        CargaOff2.Enabled = False

    End Sub

    'ACTUADOR 1: Motor enciende hacia la izquierda  

    Private Sub MotorIzq1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MotorIzq1.Click

        Motor1Val = "I"
        EnvioMensaje()

        MotorIzq1.Enabled = False
        MotorOff1.Enabled = True
        MotorDer1.Enabled = True

    End Sub

    'ACTUADOR 1: Motor enciende hacia la derecha

    Private Sub MotorDer1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MotorDer1.Click

        Motor1Val = "D"
        EnvioMensaje()

        MotorDer1.Enabled = False
        MotorOff1.Enabled = True
        MotorIzq1.Enabled = True

    End Sub

    'ACTUADOR 1: Motor apagado

    Private Sub MotorOff1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MotorOff1.Click

        Motor1Val = "O"
        EnvioMensaje()

        MotorOff1.Enabled = False
        MotorDer1.Enabled = True
        MotorIzq1.Enabled = True

    End Sub

    'ACTUADOR 2: Motor enciende a la izquierda 

    Private Sub MotorIzq2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MotorIzq2.Click

        Motor2Val = "I"
        EnvioMensaje()

        MotorIzq2.Enabled = False
        MotorOff2.Enabled = True
        MotorDer2.Enabled = True

    End Sub

    'ACTUADOR 2: Motor enciende la derecha 

    Private Sub MotorDer2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MotorDer2.Click

        Motor2Val = "D"
        EnvioMensaje()

        MotorDer2.Enabled = False
        MotorOff2.Enabled = True
        MotorIzq2.Enabled = True

    End Sub

    'ACTUADOR 2: Motor apagado

    Private Sub MotorOff2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MotorOff2.Click

        Motor2Val = "O"
        EnvioMensaje()

        MotorOff2.Enabled = False
        MotorDer2.Enabled = True
        MotorIzq2.Enabled = True

    End Sub

    'ACTUADOR 1: Carga Ctrl1 Subir

    Private Sub SubirCargaCtrl1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SubirCargaCtrl1.Click

        Dim subir As Integer = CargaCtrlVal1.Text

        If CargaCtrlVal1.Text < 100 Then
            CargaCtrlVal1.Text = subir + 5
        End If

        If CargaCtrlVal1.Text = 100 Then
            SubirCargaCtrl1.Enabled = False
        End If

        If CargaCtrlVal1.Text > 0 Then
            BajarCargaCtrl1.Enabled = True
        End If

        CargaCtrl1 = CargaCtrlVal1.Text
        EnvioMensaje()

    End Sub

    'ACTUADOR 1: Carga Ctrl1 Bajar

    Private Sub BajarCargaCtrl1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BajarCargaCtrl1.Click
        Dim bajar As Integer

        bajar = CargaCtrlVal1.Text

        If CargaCtrlVal1.Text > 0 Then
            CargaCtrlVal1.Text = bajar - 5
        End If

        If CargaCtrlVal1.Text = 0 Then
            BajarCargaCtrl1.Enabled = False
        End If


        If CargaCtrlVal1.Text < 100 Then
            SubirCargaCtrl1.Enabled = True
        End If

        CargaCtrl1 = CargaCtrlVal1.Text
        EnvioMensaje()

    End Sub

    'ACTUADOR 2: Carga Ctrl2 Subir

    Private Sub SubirCargaCtrl2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles SubirCargaCtrl2.Click

        Dim subir As Integer = CargaCtrlVal2.Text

        If CargaCtrlVal2.Text < 100 Then
            CargaCtrlVal2.Text = subir + 5
        End If

        If CargaCtrlVal2.Text = 100 Then
            SubirCargaCtrl2.Enabled = False
        End If

        If CargaCtrlVal2.Text > 0 Then
            BajarCargaCtrl2.Enabled = True
        End If

        CargaCtrl2 = CargaCtrlVal2.Text
        EnvioMensaje()

    End Sub

    'ACTUADOR 2: Carga Ctrl2 Bajar

    Private Sub BajarCargaCtrl2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BajarCargaCtrl2.Click

        Dim bajar As Integer

        bajar = CargaCtrlVal2.Text

        If CargaCtrlVal2.Text > 0 Then
            CargaCtrlVal2.Text = bajar - 5
        End If

        If CargaCtrlVal2.Text = 0 Then
            BajarCargaCtrl2.Enabled = False
        End If

        If CargaCtrlVal2.Text < 100 Then
            SubirCargaCtrl2.Enabled = True
        End If

        CargaCtrl2 = CargaCtrlVal2.Text
        EnvioMensaje()

    End Sub


    Private Sub Sinc_Sensores_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Sinc_Sensores.Tick

        If Midispositivo.Estado = True Then


            'ESTE EVENTO SE EJECUTA CADA INTERVALO DE SincSensores.Interval
            '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
            'La información que se le envía al PIC es un caracter que le indica
            '   nuestro deseo de saber el estado de cada sensor. Este es:
            '   '&'
            'La información que llega desde el PIC tiene el formato:
            '   "Enc1,Enc2,Est11,Est21,Est31,Est12,Est22,Est32,ADC1,ADC2"
            '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

            'Variables para la decodificación de la información por parte del PIC
            'Elemento tipo String para convertir lo que se recibe por midispositivo.receive(), que es tipo Byte

            Dim mensaje As String = "\0\0\0\0\0\0\0\0\0\0\0\0"

            'Se almacena información en cada elemento. Es un array de 10 elementos generalmente

            Dim mensaje_partido() As String

            Midispositivo.Send(System.Text.Encoding.ASCII.GetBytes("&"))    'Enviamos un '&' pidiendo al PIC info de los sensores
            Midispositivo.Receive(Mensaje_sensores)                         'Recibimos la información del PIC

            'Cambiamos de codificación byte_8 (UTF8) a string (ASCII) de Mensaje_sensores
            mensaje = System.Text.Encoding.UTF8.GetString(Mensaje_sensores)

            'TODO:Sirve para depuración
            Mensajes.AppendText(vbCr + mensaje)

            'Partimos el mensaje en un array de 10 elementos por medio del token ','
            mensaje_partido = mensaje.Split(",")

            'Valor de los controles API del encoder 1 y 2   (r.p.m.)
            EncoderBar1.Value = mensaje_partido(0) * 100 / 250
            EncoderTxt1.Text = mensaje_partido(0)
            EncoderBar2.Value = mensaje_partido(1) * 100 / 250
            EncoderTxt2.Text = mensaje_partido(1)

            'Los indicadores de estado de cada Switch       (ON/OFF)
            Estado1S1.Checked = mensaje_partido(2)
            Estado2S1.Checked = mensaje_partido(3)
            Estado3S1.Checked = mensaje_partido(4)
            Estado1S2.Checked = mensaje_partido(5)
            Estado2S2.Checked = mensaje_partido(6)
            Estado3S2.Checked = mensaje_partido(7)

            'Valor de cada conversor AD                     (Temperatura)
            ADConverterBar1.Value = mensaje_partido(8) * 100 / 100
            ADConverter1.Text = mensaje_partido(8)
            ADConverterBar2.Value = mensaje_partido(9) * 100 / 100
            ADConverter2.Text = mensaje_partido(9)

        End If
    End Sub


    Private Sub Créditos_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Créditos.Click
        Globo.BalloonTipTitle = "USBConverter - Universidad del Cauca"
        Globo.BalloonTipText = "Creado por:" + vbCr + "    Mónica Urbano Valderrama" + vbCr + "    Rowinson Gallego Medina" + vbCr + "    Ing. en Automática Industrial - 2009"
        Globo.ShowBalloonTip(4000)
    End Sub

    'Función de compilación
    Public Sub Compilar()

        Array.Clear(Codigo_compilado, 0, 255)

        'Variables
        Dim codigo As String
        Dim codigo_partido() As String
        Dim longitud_codigo_ant As Integer = 0

        ''''''''''''''''''''''''''''
        longitud_codigo = 0

        'Almacenamos lo que hay en el cuadro de texto
        codigo = EditorPrograma.Text

        'Partimos codigo por medio del token '\n'. Cada elemento es una instrucción
        codigo_partido = codigo.Split(vbLf)

        'Traduzco cada palabra (cada renglón)
        For i As Integer = 0 To codigo_partido.Length - 1
            'Variable de almacenamiento de cada palabra. Confluye a codigo_compilado
            Dim instruccion(7) As Byte


            If codigo_partido(i).StartsWith("actuador") Then
                '''''''''''''''     ACTUADOR    ''''''''''''

                'Primer campo
                instruccion(0) = 1

                'Segundo campo
                If codigo_partido(i).ElementAt(8) = "0" Or codigo_partido(i).ElementAt(8) = "1" Then
                    instruccion(1) = Val(codigo_partido(i).ElementAt(8)) + 3
                Else
                    'Error
                End If

                'Tercer campo
                If codigo_partido(i).Contains("carga") Then
                    instruccion(2) = 1
                    Select Case codigo_partido(i).Substring(codigo_partido(i).IndexOf("=") + 1)
                        Case "ON"
                            instruccion(3) = 1
                        Case "OFF"
                            instruccion(3) = 2
                        Case Else
                            'Error
                    End Select

                ElseIf codigo_partido(i).Contains("motor") Then
                    instruccion(2) = 2
                    Select Case codigo_partido(i).Substring(codigo_partido(i).IndexOf("=") + 1)
                        Case "D"
                            instruccion(3) = 1
                        Case "I"
                            instruccion(3) = 2
                        Case "O"
                            instruccion(3) = 3
                        Case Else
                            'Error
                    End Select

                ElseIf codigo_partido(i).Contains("potencia") Then
                    instruccion(2) = 3
                    instruccion(3) = Val(codigo_partido(i).Substring(codigo_partido(i).IndexOf("=") + 1))
                End If

                'Cuarto campo
                longitud_codigo += 4


            ElseIf codigo_partido(i).StartsWith("RAM[") And codigo_partido(i).Contains("sensor") Then
                '''''''''''''''     SENSOR      ''''''''''''

                'Primer campo
                instruccion(0) = 2

                'Segundo campo
                Dim ubi_sensor As Integer
                ubi_sensor = codigo_partido(i).IndexOf("sensor") + 6
                If codigo_partido(i).ElementAt(ubi_sensor) = "0" Or codigo_partido(i).ElementAt(ubi_sensor) = "1" Then
                    instruccion(1) = Val(codigo_partido(i).ElementAt(ubi_sensor))
                Else
                    'Error
                End If

                'Tercer campo
                If codigo_partido(i).Contains("motor") Then
                    instruccion(2) = 1
                ElseIf codigo_partido(i).Contains("temperatura") Then
                    instruccion(2) = 2
                ElseIf codigo_partido(i).Contains("switches") Then
                    instruccion(2) = 3
                End If

                'Cuarto campo
                Dim resto As String

                resto = codigo_partido(i).Remove(codigo_partido(i).IndexOf("]"))
                instruccion(3) = Val(codigo_partido(i).Substring(codigo_partido(i).IndexOf("[") + 1))

                longitud_codigo += 4

            ElseIf codigo_partido(i).StartsWith("goto") Then
                ''''''''''''''''      GOTO     '''''''''''''''

                'Primer campo
                instruccion(0) = 3

                'Segundo campo
                instruccion(1) = Val(codigo_partido(i).Substring(codigo_partido(i).IndexOf("(") + 1))

                longitud_codigo += 2

            ElseIf codigo_partido(i).StartsWith("if") Then
                '''''''''''''''''      IF     '''''''''''''''''
                'Primer campo
                instruccion(0) = 4

                'Segundo campo
                Dim resto As String
                resto = codigo_partido(i).Remove(codigo_partido(i).IndexOf("]"))
                instruccion(1) = Val(codigo_partido(i).Substring(codigo_partido(i).IndexOf("[") + 1))

                'Tercer campo
                resto = codigo_partido(i).Remove(codigo_partido(i).IndexOf("])"))
                instruccion(2) = Val(codigo_partido(i).Substring(codigo_partido(i).IndexOf("]") + 6))

                'Cuarto campo
                resto = codigo_partido(i).Remove(codigo_partido(i).IndexOf("])"))
                If resto.Contains("=") Then
                    instruccion(3) = 0
                ElseIf resto.Contains(">") Then
                    instruccion(3) = 1
                ElseIf resto.Contains("<") Then
                    instruccion(3) = 2
                Else
                    'Error[**]
                End If

                'Quinto campo
                instruccion(4) = 0
                'For indice As Integer = 0 To 255
                'Sexto campo
                Dim indice_quinto As Integer = 0
                Do While indice_quinto < 255 And indice_quinto + i < codigo_partido.Length
                    If codigo_partido(i + indice_quinto).Contains("endif") Then
                        instruccion(5) = indice_quinto - 1
                        indice_quinto = 257
                    End If
                    indice_quinto += 1
                Loop
                If instruccion(5) = 0 Then
                    'Error[**]
                End If
                longitud_codigo += 6

            ElseIf codigo_partido(i).StartsWith("RAM[") And Not codigo_partido(i).Contains("sensor") Then
                '''''''''''''''   ASIGNACION  '''''''''''''''''

                'Primer campo
                instruccion(0) = 5

                'Segundo campo
                Dim resto As String
                resto = codigo_partido(i).Remove(codigo_partido(i).IndexOf("]"))
                instruccion(1) = Val(codigo_partido(i).Substring(codigo_partido(i).IndexOf("[") + 1))

                'Tercer campo
                instruccion(2) = Val(codigo_partido(i).Substring(codigo_partido(i).IndexOf("=") + 1))

                longitud_codigo += 3

            ElseIf codigo_partido(i).StartsWith("pause") Then
                '''''''''''''''''      PAUSE    '''''''''''''''''
                'Primer campo
                instruccion(0) = 6

                'Segundo campo
                instruccion(1) = Val(codigo_partido(i).Substring(codigo_partido(i).IndexOf("(") + 1))

                longitud_codigo += 2
            Else
                'Error
            End If

            'Mostramos el código compilado
            If Not (longitud_codigo = longitud_codigo_ant) Then
                VisorPrograma.AppendText("[" & longitud_codigo_ant & "] ")
            Else
                VisorPrograma.AppendText("[--]- - - - ")
            End If
            For indice_texto As Integer = 0 To longitud_codigo - longitud_codigo_ant - 1
                Dim formatString As String = String.Format("0x{0,1:X}", instruccion(indice_texto))
                VisorPrograma.AppendText(formatString)
                VisorPrograma.AppendText(" ")
            Next
            VisorPrograma.AppendText(vbCr)


            If longitud_codigo - longitud_codigo_ant < 254 - longitud_codigo Then
                instruccion.CopyTo(Codigo_compilado, longitud_codigo_ant)
            Else
                VisorPrograma.Clear()
                VisorPrograma.Text = "Error: El máximo tamaño de memoria es de 255 instrucciones."
            End If


            longitud_codigo_ant = longitud_codigo
        Next

    End Sub

    Private Sub CompilarCodigo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles CompilarCodigo.Click
        VisorPrograma.Clear()
        Try
            Compilar()
            Mensajes.AppendText(vbCr + "[OK:] La compilación parece correcta!")
            Mensajes.ScrollToCaret()
        Catch ex As Exception
            MsgBox("Error de compilación. Revísela y corríjala")
            Mensajes.AppendText(vbCr + "[Error:] Sintaxis en el código. Revíselo y/o consulte la documentación")
            Mensajes.ScrollToCaret()
        End Try

    End Sub


    Private Sub ProgramarDispositivo_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ProgramarDispositivo.Click

        VisorPrograma.Clear()

        Try
            Compilar()
            Mensajes.AppendText(vbCr + "[OK:] La compilación parece correcta!")
            Mensajes.ScrollToCaret()
        Catch ex As Exception
            MsgBox("Error de compilación. Revísela y corríjala")
            Mensajes.AppendText(vbCr + "[Error:] Sintaxis en el código. Revíselo y/o consulte la documentación")
            Mensajes.ScrollToCaret()
        End Try

        'Enviamos la cabecera de compilación.
        'Esta es "%,ddd," indicando el número de byte a escribir.
        'Esto le da información sobre lo que va a recibir para así leer todo correctamente.
        'La información al PIC la enviamos en bloques de 20 bytes.
        Dim cabecera(3) As Byte

        Array.Copy(System.Text.Encoding.ASCII.GetBytes("%,"), cabecera, 2)
        cabecera(2) = longitud_codigo

        Midispositivo.Send(cabecera)

        Dim buffer_longitud As Integer = 0
        Dim almacen(255) As Byte

        For i_paquete As Integer = 0 To 13 - 1

            Dim buffer_codigo(20) As Byte

            For i_buffer As Integer = 0 To 20 - 1
                buffer_codigo(i_buffer) = Codigo_compilado(buffer_longitud)
                If buffer_longitud = longitud_codigo Then
                    i_paquete = 100   'Con esto nos salimos de ambos bucles
                    Exit For
                End If
                buffer_longitud += 1
            Next

            Midispositivo.Send(buffer_codigo)
            'Midispositivo.Receive(buffer_codigo)
            buffer_longitud = buffer_longitud
        Next

    End Sub
End Class

